home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / a_utils / flex / amiga / flex.lha / Flex.src.lha / gen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-13  |  31.0 KB  |  1,342 lines

  1. /* gen - actual generation (writing) of flex scanners */
  2.  
  3. /*-
  4.  * Copyright (c) 1990 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Vern Paxson.
  9.  * 
  10.  * The United States Government has rights in this work pursuant
  11.  * to contract no. DE-AC03-76SF00098 between the United States
  12.  * Department of Energy and the University of California.
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted provided
  15.  * that: (1) source distributions retain this entire copyright notice and
  16.  * comment, and (2) distributions including binaries display the following
  17.  * acknowledgement:  ``This product includes software developed by the
  18.  * University of California, Berkeley and its contributors'' in the
  19.  * documentation or other materials provided with the distribution and in
  20.  * all advertising materials mentioning features or use of this software.
  21.  * Neither the name of the University nor the names of its contributors may
  22.  * be used to endorse or promote products derived from this software without
  23.  * specific prior written permission.
  24.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  25.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  26.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  27.  */
  28.  
  29. #ifndef lint
  30. static char rcsid[] =
  31.     "@(#) $Header: /home/horse/u0/vern/flex/RCS/gen.c,v 2.12 91/03/28 12:01:38 vern Exp $ (LBL)";
  32. #endif
  33.  
  34. #include "flexdef.h"
  35.  
  36. #ifdef AMIGA
  37. #include "gen.i" /* Include the prototypes */
  38. #include "misc.i"
  39. #endif
  40.  
  41.  
  42. /* declare functions that have forward references */
  43.  
  44. void gen_next_state PROTO((int));
  45. void genecs PROTO(());
  46. void indent_put2s PROTO((char [], char []));
  47. void indent_puts PROTO((char []));
  48.  
  49.  
  50. static int indent_level = 0; /* each level is 4 spaces */
  51.  
  52. #define indent_up() (++indent_level)
  53. #define indent_down() (--indent_level)
  54. #define set_indent(indent_val) indent_level = indent_val
  55.  
  56. /* *everything* is done in terms of arrays starting at 1, so provide
  57.  * a null entry for the zero element of all C arrays
  58.  */
  59. static char C_short_decl[] = "static const short int %s[%d] =\n    {   0,\n";
  60. static char C_long_decl[] = "static const long int %s[%d] =\n    {   0,\n";
  61. static char C_state_decl[] =
  62.     "static const yy_state_type %s[%d] =\n    {   0,\n";
  63.  
  64.  
  65. /* indent to the current level */
  66.  
  67. void do_indent()
  68.  
  69.     {
  70.     register int i = indent_level * 4;
  71.  
  72.     while ( i >= 8 )
  73.     {
  74.     putchar( '\t' );
  75.     i -= 8;
  76.     }
  77.     
  78.     while ( i > 0 )
  79.     {
  80.     putchar( ' ' );
  81.     --i;
  82.     }
  83.     }
  84.  
  85.  
  86. /* generate the code to keep backtracking information */
  87.  
  88. void gen_backtracking()
  89.  
  90.     {
  91.     if ( reject || num_backtracking == 0 )
  92.     return;
  93.  
  94.     if ( fullspd )
  95.     indent_puts( "if ( yy_current_state[-1].yy_nxt )" );
  96.     else
  97.     indent_puts( "if ( yy_accept[yy_current_state] )" );
  98.  
  99.     indent_up();
  100.     indent_puts( "{" );
  101.     indent_puts( "yy_last_accepting_state = yy_current_state;" );
  102.     indent_puts( "yy_last_accepting_cpos = yy_cp;" );
  103.     indent_puts( "}" );
  104.     indent_down();
  105.     }
  106.  
  107.  
  108. /* generate the code to perform the backtrack */
  109.  
  110. void gen_bt_action()
  111.  
  112.     {
  113.     if ( reject || num_backtracking == 0 )
  114.     return;
  115.  
  116.     set_indent( 3 );
  117.  
  118.     indent_puts( "case 0: /* must backtrack */" );
  119.     indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" );
  120.     indent_puts( "*yy_cp = yy_hold_char;" );
  121.  
  122.     if ( fullspd || fulltbl )
  123.     indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" );
  124.     else
  125.     /* backtracking info for compressed tables is taken \after/
  126.      * yy_cp has been incremented for the next state
  127.      */
  128.     indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  129.  
  130.     indent_puts( "yy_current_state = yy_last_accepting_state;" );
  131.     indent_puts( "goto yy_find_action;" );
  132.     putchar( '\n' );
  133.  
  134.     set_indent( 0 );
  135.     }
  136.  
  137.  
  138. /* genctbl - generates full speed compressed transition table
  139.  *
  140.  * synopsis
  141.  *     genctbl();
  142.  */
  143.  
  144. void genctbl()
  145.  
  146.     {
  147.     register int i;
  148.     int end_of_buffer_action = num_rules + 1;
  149.  
  150.     /* table of verify for transition and offset to next state */
  151.     printf( "static const struct yy_trans_info yy_transition[%d] =\n",
  152.         tblend + numecs + 1 );
  153.     printf( "    {\n" );
  154.     
  155.     /* We want the transition to be represented as the offset to the
  156.      * next state, not the actual state number, which is what it currently is.
  157.      * The offset is base[nxt[i]] - base[chk[i]].  That's just the
  158.      * difference between the starting points of the two involved states
  159.      * (to - from).
  160.      *
  161.      * first, though, we need to find some way to put in our end-of-buffer
  162.      * flags and states.  We do this by making a state with absolutely no
  163.      * transitions.  We put it at the end of the table.
  164.      */
  165.     /* at this point, we're guaranteed that there's enough room in nxt[]
  166.      * and chk[] to hold tblend + numecs entries.  We need just two slots.
  167.      * One for the action and one for the end-of-buffer transition.  We
  168.      * now *assume* that we're guaranteed the only character we'll try to
  169.      * index this nxt/chk pair with is EOB, i.e., 0, so we don't have to
  170.      * make sure there's room for jam entries for other characters.
  171.      */
  172.  
  173.     base[lastdfa + 1] = tblend + 2;
  174.     nxt[tblend + 1] = end_of_buffer_action;
  175.     chk[tblend + 1] = numecs + 1;
  176.     chk[tblend + 2] = 1; /* anything but EOB */
  177.     nxt[tblend + 2] = 0; /* so that "make test" won't show arb. differences */
  178.  
  179.     /* make sure every state has a end-of-buffer transition and an action # */
  180.     for ( i = 0; i <= lastdfa; ++i )
  181.     {
  182.     register int anum = dfaacc[i].dfaacc_state;
  183.  
  184.     chk[base[i]] = EOB_POSITION;
  185.     chk[base[i] - 1] = ACTION_POSITION;
  186.     nxt[base[i] - 1] = anum;    /* action number */
  187.     }
  188.  
  189.     for ( i = 0; i <= tblend; ++i )
  190.     {
  191.     if ( chk[i] == EOB_POSITION )
  192.         transition_struct_out( 0, base[lastdfa + 1] - i );
  193.  
  194.     else if ( chk[i] == ACTION_POSITION )
  195.         transition_struct_out( 0, nxt[i] );
  196.  
  197.     else if ( chk[i] > numecs || chk[i] == 0 )
  198.         transition_struct_out( 0, 0 );        /* unused slot */
  199.  
  200.     else    /* verify, transition */
  201.         transition_struct_out( chk[i], base[nxt[i]] - (i - chk[i]) );
  202.     }
  203.  
  204.  
  205.     /* here's the final, end-of-buffer state */
  206.     transition_struct_out( chk[tblend + 1], nxt[tblend + 1] );
  207.     transition_struct_out( chk[tblend + 2], nxt[tblend + 2] );
  208.  
  209.     printf( "    };\n" );
  210.     printf( "\n" );
  211.  
  212.     /* table of pointers to start states */
  213.     printf( "static const struct yy_trans_info *yy_start_state_list[%d] =\n",
  214.         lastsc * 2 + 1 );
  215.     printf( "    {\n" );
  216.  
  217.     for ( i = 0; i <= lastsc * 2; ++i )
  218.     printf( "    &yy_transition[%d],\n", base[i] );
  219.  
  220.     dataend();
  221.  
  222.     if ( useecs )
  223.     genecs();
  224.     }
  225.  
  226.  
  227. /* generate equivalence-class tables */
  228.  
  229. void genecs()
  230.  
  231.     {
  232.     register int i, j;
  233.     static char C_char_decl[] = "static const %s %s[%d] =\n    {   0,\n";
  234.     int numrows;
  235.     Char clower();
  236.  
  237.     if ( numecs < csize )
  238.     printf( C_char_decl, "YY_CHAR", "yy_ec", csize );
  239.     else
  240.     printf( C_char_decl, "short", "yy_ec", csize );
  241.  
  242.     for ( i = 1; i < csize; ++i )
  243.     {
  244.     if ( caseins && (i >= 'A') && (i <= 'Z') )
  245.         ecgroup[i] = ecgroup[clower( i )];
  246.  
  247.     ecgroup[i] = abs( ecgroup[i] );
  248.     mkdata( ecgroup[i] );
  249.     }
  250.  
  251.     dataend();
  252.  
  253.     if ( trace )
  254.     {
  255.     char *readable_form();
  256.  
  257.     fputs( "\n\nEquivalence Classes:\n\n", stderr );
  258.  
  259.     numrows = csize / 8;
  260.  
  261.     for ( j = 0; j < numrows; ++j )
  262.         {
  263.         for ( i = j; i < csize; i = i + numrows )
  264.         {
  265.         fprintf( stderr, "%4s = %-2d", readable_form( i ), ecgroup[i] );
  266.  
  267.         putc( ' ', stderr );
  268.         }
  269.  
  270.         putc( '\n', stderr );
  271.         }
  272.     }
  273.     }
  274.  
  275.  
  276. /* generate the code to find the action number */
  277.  
  278. void gen_find_action()
  279.  
  280.     {
  281.     if ( fullspd )
  282.     indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" );
  283.  
  284.     else if ( fulltbl )
  285.     indent_puts( "yy_act = yy_accept[yy_current_state];" );
  286.  
  287.     else if ( reject )
  288.     {
  289.     indent_puts( "yy_current_state = *--yy_state_ptr;" );
  290.     indent_puts( "yy_lp = yy_accept[yy_current_state];" );
  291.  
  292.     puts( "find_rule: /* we branch to this label when backtracking */" );
  293.  
  294.     indent_puts( "for ( ; ; ) /* until we find what rule we matched */" );
  295.  
  296.     indent_up();
  297.  
  298.     indent_puts( "{" );
  299.  
  300.     indent_puts( "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" );
  301.     indent_up();
  302.     indent_puts( "{" );
  303.     indent_puts( "yy_act = yy_acclist[yy_lp];" );
  304.  
  305.     if ( variable_trailing_context_rules )
  306.         {
  307.         indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" );
  308.         indent_puts( "     yy_looking_for_trail_begin )" );
  309.         indent_up();
  310.         indent_puts( "{" );
  311.  
  312.         indent_puts( "if ( yy_act == yy_looking_for_trail_begin )" );
  313.         indent_up();
  314.         indent_puts( "{" );
  315.         indent_puts( "yy_looking_for_trail_begin = 0;" );
  316.         indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" );
  317.         indent_puts( "break;" );
  318.         indent_puts( "}" );
  319.         indent_down();
  320.  
  321.         indent_puts( "}" );
  322.         indent_down();
  323.  
  324.         indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" );
  325.         indent_up();
  326.         indent_puts( "{" );
  327.         indent_puts(
  328.         "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" );
  329.         indent_puts(
  330.         "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" );
  331.  
  332.         if ( real_reject )
  333.         {
  334.         /* remember matched text in case we back up due to REJECT */
  335.         indent_puts( "yy_full_match = yy_cp;" );
  336.         indent_puts( "yy_full_state = yy_state_ptr;" );
  337.         indent_puts( "yy_full_lp = yy_lp;" );
  338.         }
  339.  
  340.         indent_puts( "}" );
  341.         indent_down();
  342.  
  343.         indent_puts( "else" );
  344.         indent_up();
  345.         indent_puts( "{" );
  346.         indent_puts( "yy_full_match = yy_cp;" );
  347.         indent_puts( "yy_full_state = yy_state_ptr;" );
  348.         indent_puts( "yy_full_lp = yy_lp;" );
  349.         indent_puts( "break;" );
  350.         indent_puts( "}" );
  351.         indent_down();
  352.  
  353.         indent_puts( "++yy_lp;" );
  354.         indent_puts( "goto find_rule;" );
  355.         }
  356.  
  357.     else
  358.         {
  359.         /* remember matched text in case we back up due to trailing context
  360.          * plus REJECT
  361.          */
  362.         indent_up();
  363.         indent_puts( "{" );
  364.         indent_puts( "yy_full_match = yy_cp;" );
  365.         indent_puts( "break;" );
  366.         indent_puts( "}" );
  367.         indent_down();
  368.         }
  369.  
  370.     indent_puts( "}" );
  371.     indent_down();
  372.  
  373.     indent_puts( "--yy_cp;" );
  374.  
  375.     /* we could consolidate the following two lines with those at
  376.      * the beginning, but at the cost of complaints that we're
  377.      * branching inside a loop
  378.      */
  379.     indent_puts( "yy_current_state = *--yy_state_ptr;" );
  380.     indent_puts( "yy_lp = yy_accept[yy_current_state];" );
  381.  
  382.     indent_puts( "}" );
  383.  
  384.     indent_down();
  385.     }
  386.  
  387.     else
  388.     /* compressed */
  389.     indent_puts( "yy_act = yy_accept[yy_current_state];" );
  390.     }
  391.  
  392.  
  393. /* genftbl - generates full transition table
  394.  *
  395.  * synopsis
  396.  *     genftbl();
  397.  */
  398.  
  399. void genftbl()
  400.  
  401.     {
  402.     register int i;
  403.     int end_of_buffer_action = num_rules + 1;
  404.  
  405.     printf( C_short_decl, "yy_accept", lastdfa + 1 );
  406.  
  407.  
  408.     dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
  409.  
  410.     for ( i = 1; i <= lastdfa; ++i )
  411.     {
  412.     register int anum = dfaacc[i].dfaacc_state;
  413.  
  414.     mkdata( anum );
  415.  
  416.     if ( trace && anum )
  417.         fprintf( stderr, "state # %d accepts: [%d]\n", i, anum );
  418.     }
  419.  
  420.     dataend();
  421.  
  422.     if ( useecs )
  423.     genecs();
  424.  
  425.     /* don't have to dump the actual full table entries - they were created
  426.      * on-the-fly
  427.      */
  428.     }
  429.  
  430.  
  431. /* generate the code to find the next compressed-table state */
  432.  
  433. void gen_next_compressed_state( char_map )
  434. char *char_map;
  435.  
  436.     {
  437.     indent_put2s( "register YY_CHAR yy_c = %s;", char_map );
  438.  
  439.     /* save the backtracking info \before/ computing the next state
  440.      * because we always compute one more state than needed - we
  441.      * always proceed until we reach a jam state
  442.      */
  443.     gen_backtracking();
  444.  
  445.     indent_puts(
  446.     "while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" );
  447.     indent_up();
  448.     indent_puts( "{" );
  449.     indent_puts( "yy_current_state = yy_def[yy_current_state];" );
  450.  
  451.     if ( usemecs )
  452.     {
  453.     /* we've arrange it so that templates are never chained
  454.      * to one another.  This means we can afford make a
  455.      * very simple test to see if we need to convert to
  456.      * yy_c's meta-equivalence class without worrying
  457.      * about erroneously looking up the meta-equivalence
  458.      * class twice
  459.      */
  460.     do_indent();
  461.     /* lastdfa + 2 is the beginning of the templates */
  462.     printf( "if ( yy_current_state >= %d )\n", lastdfa + 2 );
  463.  
  464.     indent_up();
  465.     indent_puts( "yy_c = yy_meta[yy_c];" );
  466.     indent_down();
  467.     }
  468.  
  469.     indent_puts( "}" );
  470.     indent_down();
  471.  
  472.     indent_puts(
  473.     "yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];" );
  474.     }
  475.  
  476.  
  477. /* generate the code to find the next match */
  478.  
  479. void gen_next_match()
  480.  
  481.     {
  482.     /* NOTE - changes in here should be reflected in gen_next_state() and
  483.      * gen_NUL_trans()
  484.      */
  485.     char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp";
  486.     char *char_map_2 = useecs ? "yy_ec[*++yy_cp]" : "*++yy_cp";
  487.     
  488.     if ( fulltbl )
  489.     {
  490.     indent_put2s(
  491.         "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )",
  492.         char_map );
  493.  
  494.     indent_up();
  495.  
  496.     if ( num_backtracking > 0 )
  497.         {
  498.         indent_puts( "{" );
  499.         gen_backtracking();
  500.         putchar( '\n' );
  501.         }
  502.  
  503.     indent_puts( "++yy_cp;" );
  504.  
  505.     if ( num_backtracking > 0 )
  506.         indent_puts( "}" );
  507.  
  508.     indent_down();
  509.  
  510.     putchar( '\n' );
  511.     indent_puts( "yy_current_state = -yy_current_state;" );
  512.     }
  513.  
  514.     else if ( fullspd )
  515.     {
  516.     indent_puts( "{" );
  517.     indent_puts( "register const struct yy_trans_info *yy_trans_info;\n" );
  518.     indent_puts( "register YY_CHAR yy_c;\n" );
  519.     indent_put2s( "for ( yy_c = %s;", char_map );
  520.     indent_puts(
  521.     "      (yy_trans_info = &yy_current_state[yy_c])->yy_verify == yy_c;" );
  522.     indent_put2s( "      yy_c = %s )", char_map_2 );
  523.  
  524.     indent_up();
  525.  
  526.     if ( num_backtracking > 0 )
  527.         indent_puts( "{" );
  528.  
  529.     indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
  530.  
  531.     if ( num_backtracking > 0 )
  532.         {
  533.         putchar( '\n' );
  534.         gen_backtracking();
  535.         indent_puts( "}" );
  536.         }
  537.  
  538.     indent_down();
  539.     indent_puts( "}" );
  540.     }
  541.  
  542.     else
  543.     { /* compressed */
  544.     indent_puts( "do" );
  545.  
  546.     indent_up();
  547.     indent_puts( "{" );
  548.  
  549.     gen_next_state( false );
  550.  
  551.     indent_puts( "++yy_cp;" );
  552.  
  553.     indent_puts( "}" );
  554.     indent_down();
  555.  
  556.     do_indent();
  557.  
  558.     if ( interactive )
  559.         printf( "while ( yy_base[yy_current_state] != %d );\n", jambase );
  560.     else
  561.         printf( "while ( yy_current_state != %d );\n", jamstate );
  562.  
  563.     if ( ! reject && ! interactive )
  564.         {
  565.         /* do the guaranteed-needed backtrack to figure out the match */
  566.         indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  567.         indent_puts( "yy_current_state = yy_last_accepting_state;" );
  568.         }
  569.     }
  570.     }
  571.  
  572.  
  573. /* generate the code to find the next state */
  574.  
  575. void gen_next_state( worry_about_NULs )
  576. int worry_about_NULs;
  577.  
  578.     { /* NOTE - changes in here should be reflected in get_next_match() */
  579.     char char_map[256];
  580.  
  581.     if ( worry_about_NULs && ! nultrans )
  582.     {
  583.     if ( useecs )
  584.         (void) sprintf( char_map, "(*yy_cp ? yy_ec[*yy_cp] : %d)", NUL_ec );
  585.     else
  586.         (void) sprintf( char_map, "(*yy_cp ? *yy_cp : %d)", NUL_ec );
  587.     }
  588.  
  589.     else
  590.     (void) strcpy( char_map, useecs ? "yy_ec[*yy_cp]" : "*yy_cp" );
  591.  
  592.     if ( worry_about_NULs && nultrans )
  593.     {
  594.     if ( ! fulltbl && ! fullspd )
  595.         /* compressed tables backtrack *before* they match */
  596.         gen_backtracking();
  597.  
  598.     indent_puts( "if ( *yy_cp )" );
  599.     indent_up();
  600.     indent_puts( "{" );
  601.     }
  602.    
  603.     if ( fulltbl )
  604.     indent_put2s( "yy_current_state = yy_nxt[yy_current_state][%s];", 
  605.         char_map );
  606.     
  607.     else if ( fullspd )
  608.     indent_put2s( "yy_current_state += yy_current_state[%s].yy_nxt;",
  609.             char_map );
  610.  
  611.     else
  612.     gen_next_compressed_state( char_map );
  613.  
  614.     if ( worry_about_NULs && nultrans )
  615.     {
  616.     indent_puts( "}" );
  617.     indent_down();
  618.     indent_puts( "else" );
  619.     indent_up();
  620.     indent_puts( "yy_current_state = yy_NUL_trans[yy_current_state];" );
  621.     indent_down();
  622.     }
  623.     
  624.     if ( fullspd || fulltbl )
  625.     gen_backtracking();
  626.  
  627.     if ( reject )
  628.     indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  629.     }
  630.  
  631.  
  632. /* generate the code to make a NUL transition */
  633.  
  634. void gen_NUL_trans()
  635.  
  636.     { /* NOTE - changes in here should be reflected in get_next_match() */
  637.     int need_backtracking = (num_backtracking > 0 && ! reject);
  638.  
  639.     if ( need_backtracking )
  640.     /* we'll need yy_cp lying around for the gen_backtracking() */
  641.     indent_puts( "register YY_CHAR *yy_cp = yy_c_buf_p;" );
  642.  
  643.     putchar( '\n' );
  644.  
  645.     if ( nultrans )
  646.     {
  647.     indent_puts( "yy_current_state = yy_NUL_trans[yy_current_state];" );
  648.     indent_puts( "yy_is_jam = (yy_current_state == 0);" );
  649.     }
  650.  
  651.     else if ( fulltbl )
  652.     {
  653.     do_indent();
  654.     printf( "yy_current_state = yy_nxt[yy_current_state][%d];\n",
  655.         NUL_ec );
  656.     indent_puts( "yy_is_jam = (yy_current_state <= 0);" );
  657.     }
  658.  
  659.     else if ( fullspd )
  660.     {
  661.     do_indent();
  662.     printf( "register int yy_c = %d;\n", NUL_ec );
  663.  
  664.     indent_puts(
  665.         "register const struct yy_trans_info *yy_trans_info;\n" );
  666.     indent_puts( "yy_trans_info = &yy_current_state[yy_c];" );
  667.     indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" );
  668.  
  669.     indent_puts( "yy_is_jam = (yy_trans_info->yy_verify != yy_c);" );
  670.     }
  671.  
  672.     else
  673.     {
  674.     char NUL_ec_str[20];
  675.  
  676.     (void) sprintf( NUL_ec_str, "%d", NUL_ec );
  677.     gen_next_compressed_state( NUL_ec_str );
  678.  
  679.     if ( reject )
  680.         indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  681.  
  682.     do_indent();
  683.  
  684.     if ( interactive )
  685.         printf( "yy_is_jam = (yy_base[yy_current_state] == %d);\n",
  686.             jambase );
  687.     else
  688.         printf( "yy_is_jam = (yy_current_state == %d);\n", jamstate );
  689.     }
  690.  
  691.     /* if we've entered an accepting state, backtrack; note that
  692.      * compressed tables have *already* done such backtracking, so
  693.      * we needn't bother with it again
  694.      */
  695.     if ( need_backtracking && (fullspd || fulltbl) )
  696.     {
  697.     putchar( '\n' );
  698.     indent_puts( "if ( ! yy_is_jam )" );
  699.     indent_up();
  700.     indent_puts( "{" );
  701.     gen_backtracking();
  702.     indent_puts( "}" );
  703.     indent_down();
  704.     }
  705.     }
  706.  
  707.  
  708. /* generate the code to find the start state */
  709.  
  710. void gen_start_state()
  711.  
  712.     {
  713.     if ( fullspd )
  714.     indent_put2s( "yy_current_state = yy_start_state_list[yy_start%s];",
  715.         bol_needed ? " + (yy_bp[-1] == '\\n' ? 1 : 0)" : "" );
  716.  
  717.     else
  718.     {
  719.     indent_puts( "yy_current_state = yy_start;" );
  720.  
  721.     if ( bol_needed )
  722.         {
  723.         indent_puts( "if ( yy_bp[-1] == '\\n' )" );
  724.         indent_up();
  725.         indent_puts( "++yy_current_state;" );
  726.         indent_down();
  727.         }
  728.  
  729.     if ( reject )
  730.         {
  731.         /* set up for storing up states */
  732.         indent_puts( "yy_state_ptr = yy_state_buf;" );
  733.         indent_puts( "*yy_state_ptr++ = yy_current_state;" );
  734.         }
  735.     }
  736.     }
  737.  
  738.  
  739. /* gentabs - generate data statements for the transition tables
  740.  *
  741.  * synopsis
  742.  *    gentabs();
  743.  */
  744.  
  745. void gentabs()
  746.  
  747.     {
  748.     int i, j, k, *accset, nacc, *acc_array, total_states;
  749.     int end_of_buffer_action = num_rules + 1;
  750.  
  751.     /* *everything* is done in terms of arrays starting at 1, so provide
  752.      * a null entry for the zero element of all C arrays
  753.      */
  754.     static char C_char_decl[] =
  755.     "static const YY_CHAR %s[%d] =\n    {   0,\n";
  756.  
  757.     acc_array = allocate_integer_array( current_max_dfas );
  758.     nummt = 0;
  759.  
  760.     /* the compressed table format jams by entering the "jam state",
  761.      * losing information about the previous state in the process.
  762.      * In order to recover the previous state, we effectively need
  763.      * to keep backtracking information.
  764.      */
  765.     ++num_backtracking;
  766.  
  767.     if ( reject )
  768.     {
  769.     /* write out accepting list and pointer list
  770.      *
  771.      * first we generate the "yy_acclist" array.  In the process, we compute
  772.      * the indices that will go into the "yy_accept" array, and save the
  773.      * indices in the dfaacc array
  774.      */
  775.     int EOB_accepting_list[2];
  776.  
  777.     /* set up accepting structures for the End Of Buffer state */
  778.     EOB_accepting_list[0] = 0;
  779.     EOB_accepting_list[1] = end_of_buffer_action;
  780.     accsiz[end_of_buffer_state] = 1;
  781.     dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list;
  782.  
  783.     printf( C_short_decl, "yy_acclist", max( numas, 1 ) + 1 );
  784.  
  785.     j = 1;    /* index into "yy_acclist" array */
  786.  
  787.     for ( i = 1; i <= lastdfa; ++i )
  788.         {
  789.         acc_array[i] = j;
  790.  
  791.         if ( accsiz[i] != 0 )
  792.         {
  793.         accset = dfaacc[i].dfaacc_set;
  794.         nacc = accsiz[i];
  795.  
  796.         if ( trace )
  797.             fprintf( stderr, "state # %d accepts: ", i );
  798.  
  799.         for ( k = 1; k <= nacc; ++k )
  800.             {
  801.             int accnum = accset[k];
  802.  
  803.             ++j;
  804.  
  805.             if ( variable_trailing_context_rules &&
  806.              ! (accnum & YY_TRAILING_HEAD_MASK) &&
  807.              accnum > 0 && accnum <= num_rules &&
  808.              rule_type[accnum] == RULE_VARIABLE )
  809.             {
  810.             /* special hack to flag accepting number as part
  811.              * of trailing context rule
  812.              */
  813.             accnum |= YY_TRAILING_MASK;
  814.             }
  815.  
  816.             mkdata( accnum );
  817.  
  818.             if ( trace )
  819.             {
  820.             fprintf( stderr, "[%d]", accset[k] );
  821.  
  822.             if ( k < nacc )
  823.                 fputs( ", ", stderr );
  824.             else
  825.                 putc( '\n', stderr );
  826.             }
  827.             }
  828.         }
  829.         }
  830.  
  831.     /* add accepting number for the "jam" state */
  832.     acc_array[i] = j;
  833.  
  834.     dataend();
  835.     }
  836.  
  837.     else
  838.     {
  839.     dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
  840.  
  841.     for ( i = 1; i <= lastdfa; ++i )
  842.         acc_array[i] = dfaacc[i].dfaacc_state;
  843.  
  844.     /* add accepting number for jam state */
  845.     acc_array[i] = 0;
  846.     }
  847.  
  848.     /* spit out "yy_accept" array.  If we're doing "reject", it'll be pointers
  849.      * into the "yy_acclist" array.  Otherwise it's actual accepting numbers.
  850.      * In either case, we just dump the numbers.
  851.      */
  852.  
  853.     /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays
  854.      * beginning at 0 and for "jam" state
  855.      */
  856.     k = lastdfa + 2;
  857.  
  858.     if ( reject )
  859.     /* we put a "cap" on the table associating lists of accepting
  860.      * numbers with state numbers.  This is needed because we tell
  861.      * where the end of an accepting list is by looking at where
  862.      * the list for the next state starts.
  863.      */
  864.     ++k;
  865.  
  866.     printf( C_short_decl, "yy_accept", k );
  867.  
  868.     for ( i = 1; i <= lastdfa; ++i )
  869.     {
  870.     mkdata( acc_array[i] );
  871.  
  872.     if ( ! reject && trace && acc_array[i] )
  873.         fprintf( stderr, "state # %d accepts: [%d]\n", i, acc_array[i] );
  874.     }
  875.  
  876.     /* add entry for "jam" state */
  877.     mkdata( acc_array[i] );
  878.  
  879.     if ( reject )
  880.     /* add "cap" for the list */
  881.     mkdata( acc_array[i] );
  882.  
  883.     dataend();
  884.  
  885.     if ( useecs )
  886.     genecs();
  887.  
  888.     if ( usemecs )
  889.     {
  890.     /* write out meta-equivalence classes (used to index templates with) */
  891.  
  892.     if ( trace )
  893.         fputs( "\n\nMeta-Equivalence Classes:\n", stderr );
  894.  
  895.     printf( C_char_decl, "yy_meta", numecs + 1 );
  896.  
  897.     for ( i = 1; i <= numecs; ++i )
  898.         {
  899.         if ( trace )
  900.         fprintf( stderr, "%d = %d\n", i, abs( tecbck[i] ) );
  901.  
  902.         mkdata( abs( tecbck[i] ) );
  903.         }
  904.  
  905.     dataend();
  906.     }
  907.  
  908.     total_states = lastdfa + numtemps;
  909.  
  910.     printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,
  911.         "yy_base", total_states + 1 );
  912.  
  913.     for ( i = 1; i <= lastdfa; ++i )
  914.     {
  915.     register int d = def[i];
  916.  
  917.     if ( base[i] == JAMSTATE )
  918.         base[i] = jambase;
  919.  
  920.     if ( d == JAMSTATE )
  921.         def[i] = jamstate;
  922.  
  923.     else if ( d < 0 )
  924.         {
  925.         /* template reference */
  926.         ++tmpuses;
  927.         def[i] = lastdfa - d + 1;
  928.         }
  929.  
  930.     mkdata( base[i] );
  931.     }
  932.  
  933.     /* generate jam state's base index */
  934.     mkdata( base[i] );
  935.  
  936.     for ( ++i /* skip jam state */; i <= total_states; ++i )
  937.     {
  938.     mkdata( base[i] );
  939.     def[i] = jamstate;
  940.     }
  941.  
  942.     dataend();
  943.  
  944.     printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl,
  945.         "yy_def", total_states + 1 );
  946.  
  947.     for ( i = 1; i <= total_states; ++i )
  948.     mkdata( def[i] );
  949.  
  950.     dataend();
  951.  
  952.     printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,
  953.         "yy_nxt", tblend + 1 );
  954.  
  955.     for ( i = 1; i <= tblend; ++i )
  956.     {
  957.     if ( nxt[i] == 0 || chk[i] == 0 )
  958.         nxt[i] = jamstate;    /* new state is the JAM state */
  959.  
  960.     mkdata( nxt[i] );
  961.     }
  962.  
  963.     dataend();
  964.  
  965.     printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl,
  966.         "yy_chk", tblend + 1 );
  967.  
  968.     for ( i = 1; i <= tblend; ++i )
  969.     {
  970.     if ( chk[i] == 0 )
  971.         ++nummt;
  972.  
  973.     mkdata( chk[i] );
  974.     }
  975.  
  976.     dataend();
  977.     }
  978.  
  979.  
  980. /* write out a formatted string (with a secondary string argument) at the
  981.  * current indentation level, adding a final newline
  982.  */
  983.  
  984. void indent_put2s( fmt, arg )
  985. char fmt[], arg[];
  986.  
  987.     {
  988.     do_indent();
  989.     printf( fmt, arg );
  990.     putchar( '\n' );
  991.     }
  992.  
  993.  
  994. /* write out a string at the current indentation level, adding a final
  995.  * newline
  996.  */
  997.  
  998. void indent_puts( str )
  999. char str[];
  1000.  
  1001.     {
  1002.     do_indent();
  1003.     puts( str );
  1004.     }
  1005.  
  1006.  
  1007. /* make_tables - generate transition tables
  1008.  *
  1009.  * synopsis
  1010.  *     make_tables();
  1011.  *
  1012.  * Generates transition tables and finishes generating output file
  1013.  */
  1014.  
  1015. void make_tables()
  1016.  
  1017.     {
  1018.     register int i;
  1019.     int did_eof_rule = false;
  1020.  
  1021.     skelout();
  1022.  
  1023.     /* first, take care of YY_DO_BEFORE_ACTION depending on yymore being used */
  1024.     set_indent( 2 );
  1025.  
  1026.     if ( yymore_used )
  1027.     {
  1028.     indent_puts( "yytext -= yy_more_len; \\" );
  1029.     indent_puts( "yyleng = yy_cp - yytext; \\" );
  1030.     }
  1031.  
  1032.     else
  1033.     indent_puts( "yyleng = yy_cp - yy_bp; \\" );
  1034.  
  1035.     set_indent( 0 );
  1036.     
  1037.     skelout();
  1038.  
  1039.  
  1040.     printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 );
  1041.  
  1042.     if ( fullspd )
  1043.     { /* need to define the transet type as a size large
  1044.        * enough to hold the biggest offset
  1045.        */
  1046.     int total_table_size = tblend + numecs + 1;
  1047.     char *trans_offset_type =
  1048.         total_table_size > MAX_SHORT ? "long" : "short";
  1049.  
  1050.     set_indent( 0 );
  1051.     indent_puts( "struct yy_trans_info" );
  1052.     indent_up();
  1053.         indent_puts( "{" );
  1054.         indent_puts( "short yy_verify;" );
  1055.  
  1056.         /* in cases where its sister yy_verify *is* a "yes, there is a
  1057.      * transition", yy_nxt is the offset (in records) to the next state.
  1058.      * In most cases where there is no transition, the value of yy_nxt
  1059.      * is irrelevant.  If yy_nxt is the -1th  record of a state, though,
  1060.      * then yy_nxt is the action number for that state
  1061.          */
  1062.  
  1063.         indent_put2s( "%s yy_nxt;", trans_offset_type );
  1064.         indent_puts( "};" );
  1065.     indent_down();
  1066.  
  1067.     indent_puts( "typedef const struct yy_trans_info *yy_state_type;" );
  1068.     }
  1069.     
  1070.     else
  1071.     indent_puts( "typedef int yy_state_type;" );
  1072.  
  1073.     if ( fullspd )
  1074.     genctbl();
  1075.  
  1076.     else if ( fulltbl )
  1077.     genftbl();
  1078.  
  1079.     else
  1080.     gentabs();
  1081.  
  1082.     if ( num_backtracking > 0 )
  1083.     {
  1084.     indent_puts( "static yy_state_type yy_last_accepting_state;" );
  1085.     indent_puts( "static YY_CHAR *yy_last_accepting_cpos;\n" );
  1086.     }
  1087.  
  1088.     if ( nultrans )
  1089.     {
  1090.     printf( C_state_decl, "yy_NUL_trans", lastdfa + 1 );
  1091.  
  1092.     for ( i = 1; i <= lastdfa; ++i )
  1093.         {
  1094.         if ( fullspd )
  1095.         {
  1096.         if ( nultrans )
  1097.             printf( "    &yy_transition[%d],\n", base[i] );
  1098.         else
  1099.             printf( "    0,\n" );
  1100.         }
  1101.         
  1102.         else
  1103.         mkdata( nultrans[i] );
  1104.         }
  1105.  
  1106.     dataend();
  1107.     }
  1108.  
  1109.     if ( ddebug )
  1110.     { /* spit out table mapping rules to line numbers */
  1111.     indent_puts( "extern int yy_flex_debug;" );
  1112.     indent_puts( "int yy_flex_debug = 1;\n" );
  1113.  
  1114.     printf( C_short_decl, "yy_rule_linenum", num_rules );
  1115.     for ( i = 1; i < num_rules; ++i )
  1116.         mkdata( rule_linenum[i] );
  1117.     dataend();
  1118.     }
  1119.  
  1120.     if ( reject )
  1121.     {
  1122.     /* declare state buffer variables */
  1123.     puts(
  1124.     "static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" );
  1125.     puts( "static YY_CHAR *yy_full_match;" );
  1126.     puts( "static int yy_lp;" );
  1127.  
  1128.     if ( variable_trailing_context_rules )
  1129.         {
  1130.         puts( "static int yy_looking_for_trail_begin = 0;" );
  1131.         puts( "static int yy_full_lp;" );
  1132.         puts( "static int *yy_full_state;" );
  1133.         printf( "#define YY_TRAILING_MASK 0x%x\n", YY_TRAILING_MASK );
  1134.         printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n",
  1135.             YY_TRAILING_HEAD_MASK );
  1136.         }
  1137.  
  1138.     puts( "#define REJECT \\" );
  1139.         puts( "{ \\" );
  1140.         puts(
  1141.     "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" );
  1142.         puts(
  1143.         "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" );
  1144.  
  1145.     if ( variable_trailing_context_rules )
  1146.         {
  1147.         puts( "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" );
  1148.         puts(
  1149.         "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" );
  1150.         puts(
  1151.         "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" );
  1152.         }
  1153.  
  1154.         puts( "++yy_lp; \\" );
  1155.         puts( "goto find_rule; \\" );
  1156.         puts( "}" );
  1157.     }
  1158.     
  1159.     else
  1160.     {
  1161.     puts( "/* the intent behind this definition is that it'll catch" );
  1162.     puts( " * any uses of REJECT which flex missed" );
  1163.     puts( " */" );
  1164.     puts( "#define REJECT reject_used_but_not_detected" );
  1165.     }
  1166.     
  1167.     if ( yymore_used )
  1168.     {
  1169.     indent_puts( "static int yy_more_flag = 0;" );
  1170.     indent_puts( "static int yy_doing_yy_more = 0;" );
  1171.     indent_puts( "static int yy_more_len = 0;" );
  1172.     indent_puts(
  1173.         "#define yymore() { yy_more_flag = 1; }" );
  1174.     indent_puts(
  1175.         "#define YY_MORE_ADJ (yy_doing_yy_more ? yy_more_len : 0)" );
  1176.     }
  1177.  
  1178.     else
  1179.     {
  1180.     indent_puts( "#define yymore() yymore_used_but_not_detected" );
  1181.     indent_puts( "#define YY_MORE_ADJ 0" );
  1182.     }
  1183.  
  1184.     skelout();
  1185.  
  1186.     if ( ferror( temp_action_file ) )
  1187.     flexfatal( "error occurred when writing temporary action file" );
  1188.  
  1189.     else if ( fclose( temp_action_file ) )
  1190.     flexfatal( "error occurred when closing temporary action file" );
  1191.  
  1192.     temp_action_file = fopen( action_file_name, "r" );
  1193.  
  1194.     if ( temp_action_file == NULL )
  1195.     flexfatal( "could not re-open temporary action file" );
  1196.  
  1197.     /* copy prolog from action_file to output file */
  1198.     action_out();
  1199.  
  1200.     skelout();
  1201.  
  1202.     set_indent( 2 );
  1203.  
  1204.     if ( yymore_used )
  1205.     {
  1206.     indent_puts( "yy_more_len = 0;" );
  1207.     indent_puts( "yy_doing_yy_more = yy_more_flag;" );
  1208.     indent_puts( "if ( yy_doing_yy_more )" );
  1209.     indent_up();
  1210.     indent_puts( "{" );
  1211.     indent_puts( "yy_more_len = yyleng;" );
  1212.     indent_puts( "yy_more_flag = 0;" );
  1213.     indent_puts( "}" );
  1214.     indent_down();
  1215.     }
  1216.  
  1217.     skelout();
  1218.  
  1219.     gen_start_state();
  1220.  
  1221.     /* note, don't use any indentation */
  1222.     puts( "yy_match:" );
  1223.     gen_next_match();
  1224.  
  1225.     skelout();
  1226.     set_indent( 2 );
  1227.     gen_find_action();
  1228.  
  1229.     skelout();
  1230.     if ( ddebug )
  1231.     {
  1232.     indent_puts( "if ( yy_flex_debug )" );
  1233.     indent_up();
  1234.  
  1235.     indent_puts( "{" );
  1236.     indent_puts( "if ( yy_act == 0 )" );
  1237.     indent_up();
  1238.     indent_puts( "fprintf( stderr, \"--scanner backtracking\\n\" );" );
  1239.     indent_down();
  1240.  
  1241.     do_indent();
  1242.     printf( "else if ( yy_act < %d )\n", num_rules );
  1243.     indent_up();
  1244.     indent_puts(
  1245.     "fprintf( stderr, \"--accepting rule at line %d (\\\"%s\\\")\\n\"," );
  1246.     indent_puts( "         yy_rule_linenum[yy_act], yytext );" );
  1247.     indent_down();
  1248.  
  1249.     do_indent();
  1250.     printf( "else if ( yy_act == %d )\n", num_rules );
  1251.     indent_up();
  1252.     indent_puts(
  1253.     "fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\"," );
  1254.     indent_puts( "         yytext );" );
  1255.     indent_down();
  1256.  
  1257.     do_indent();
  1258.     printf( "else if ( yy_act == %d )\n", num_rules + 1 );
  1259.     indent_up();
  1260.     indent_puts( "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );" );
  1261.     indent_down();
  1262.  
  1263.     do_indent();
  1264.     printf( "else\n" );
  1265.     indent_up();
  1266.     indent_puts( "fprintf( stderr, \"--EOF\\n\" );" );
  1267.     indent_down();
  1268.  
  1269.     indent_puts( "}" );
  1270.     indent_down();
  1271.     }
  1272.  
  1273.     /* copy actions from action_file to output file */
  1274.     skelout();
  1275.     indent_up();
  1276.     gen_bt_action();
  1277.     action_out();
  1278.  
  1279.     /* generate cases for any missing EOF rules */
  1280.     for ( i = 1; i <= lastsc; ++i )
  1281.     if ( ! sceof[i] )
  1282.         {
  1283.         do_indent();
  1284.         printf( "case YY_STATE_EOF(%s):\n", scname[i] );
  1285.         did_eof_rule = true;
  1286.         }
  1287.     
  1288.     if ( did_eof_rule )
  1289.     {
  1290.     indent_up();
  1291.     indent_puts( "yyterminate();" );
  1292.     indent_down();
  1293.     }
  1294.  
  1295.  
  1296.     /* generate code for handling NUL's, if needed */
  1297.  
  1298.     /* first, deal with backtracking and setting up yy_cp if the scanner
  1299.      * finds that it should JAM on the NUL
  1300.      */
  1301.     skelout();
  1302.     set_indent( 7 );
  1303.  
  1304.     if ( fullspd || fulltbl )
  1305.     indent_puts( "yy_cp = yy_c_buf_p;" );
  1306.     
  1307.     else
  1308.     { /* compressed table */
  1309.     if ( ! reject && ! interactive )
  1310.         {
  1311.         /* do the guaranteed-needed backtrack to figure out the match */
  1312.         indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  1313.         indent_puts( "yy_current_state = yy_last_accepting_state;" );
  1314.         }
  1315.     }
  1316.  
  1317.  
  1318.     /* generate code for yy_get_previous_state() */
  1319.     set_indent( 1 );
  1320.     skelout();
  1321.  
  1322.     if ( bol_needed )
  1323.     indent_puts( "register YY_CHAR *yy_bp = yytext;\n" );
  1324.  
  1325.     gen_start_state();
  1326.  
  1327.     set_indent( 2 );
  1328.     skelout();
  1329.     gen_next_state( true );
  1330.  
  1331.     set_indent( 1 );
  1332.     skelout();
  1333.     gen_NUL_trans();
  1334.  
  1335.     skelout();
  1336.  
  1337.     /* copy remainder of input to output */
  1338.  
  1339.     line_directive_out( stdout );
  1340.     (void) flexscan(); /* copy remainder of input to output */
  1341.     }
  1342.